package com.atwisdom.star.auth.business.Impl;

import cn.hutool.core.util.StrUtil;
import com.atwisdom.star.auth.business.AuthBaseBslService;
import com.atwisdom.star.auth.business.UserAccountBslService;
import com.atwisdom.star.auth.pojo.AccountRole;
import com.atwisdom.star.auth.pojo.UserAccount;
import com.atwisdom.star.auth.service.AccountRoleService;
import com.atwisdom.star.auth.service.impl.RoleServiceImpl;
import com.atwisdom.star.auth.service.impl.UserAccountServiceImpl;
import com.atwisdom.star.common.actionType.auth.UserAccountActionType;
import com.atwisdom.star.common.util.JwtTokenMap;
import com.atwisdom.star.common.util.JwtUtils;
import com.atwisdom.star.common.vo.*;
import com.atwisdom.star.exception.pojo.BusinessException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 业务处理类
 */
@Service
public class UserAccountBslServiceImpl extends AuthBaseBslService<UserAccount, UserAccount> implements UserAccountBslService {

    /**
     * JWT的签发者
     **/
    @Value("${jwt.iss}")
    private String jwtIss;

    /**
     * JWT过期时间
     **/
    @Value("${jwt.expires}")
    private Long JwtExpires;

    /**
     * JWT的签发者
     **/
    @Value("${jwt.secret}")
    private String jwtSecret;


    private UserAccountServiceImpl accountServiceImpl;
    private AccountRoleService accountRoleService;

    public UserAccountBslServiceImpl(UserAccountServiceImpl accountServiceImpl,AccountRoleService accountRoleService) {
        this.accountServiceImpl = accountServiceImpl;
        this.accountRoleService = accountRoleService;
    }


    /**
     * 服务工厂方法
     *
     * @param actionDataList 参数
     * @return 参数
     * @throws BusinessException 异常
     */
    @Transactional
    public ResultInfo<?> responseFactory(List<ActionData<UserAccount>> actionDataList) throws BusinessException {
        ResultInfo<?> resultInfo = null;
        for (ActionData<UserAccount> actionData : actionDataList) {
            String action = actionData.getAction();
            UserAccountActionType actionType = UserAccountActionType.valueOf(action);
            String methodName = actionType.getMethodName();
            resultInfo = this.execMethod(methodName, actionData);
        }
        return resultInfo;
    }

    /**
     * 反射执行业务方法
     *
     * @param methodName 方法名称
     * @param actionData 接收参数
     * @return 返回统一结果类型(ResultInfo)
     * @throws BusinessException 业务数据异常
     */
    public ResultInfo<?> execMethod(String methodName, ActionData<UserAccount> actionData) throws BusinessException {
        Class<? extends UserAccountBslServiceImpl> clz = this.getClass();
        Method method;
        try {
            method = clz.getMethod(methodName, ActionData.class);
            return (ResultInfo<?>) method.invoke(this, actionData);
        } catch (NoSuchMethodException ex) {
            throw new BusinessException("999999", "没有找到该方法(" + methodName + ")", ex);
        } catch (IllegalAccessException ex) {
            throw new BusinessException("999999", "没有访问该方法权限(" + methodName + ")", ex);
        } catch (InvocationTargetException ex) {
            Throwable targetException = ex.getTargetException();
            if (targetException instanceof BusinessException) {
                BusinessException bex = (BusinessException) targetException;
                throw new BusinessException("999999", bex.getErrorMsg(), ex);
            } else {
                throw new BusinessException("999999", "出错了请重试：(" + methodName + ")---" + ex.getMessage(), ex);
            }
        }
    }

    /**
     * 用户登录
     *
     * @param param 登录参数
     * @return 反回登录信息
     * @throws BusinessException 业务处理异常
     */
    @Override
    public LoginInfo<UserAccount> Login(Map<String, String> param) throws BusinessException {
        String account = param.get("account");
        String password = param.get("password");
        LoginInfo<UserAccount> loginInfo = new LoginInfo<>();
        //登录用户账号为空值
        if (StringUtils.isBlank(account)){
            loginInfo.setSuccess(false);
            loginInfo.setCode(StatusCode.ACCOUNT_CAN_NOT_BE_EMPTY.getCode());
            loginInfo.setMessage(StatusCode.ACCOUNT_CAN_NOT_BE_EMPTY.getMessage());
            return loginInfo;
        }
        //登录的用记账号密为空值错误
        if(StringUtils.isBlank(password)){
            loginInfo.setSuccess(false);
            loginInfo.setCode(StatusCode.PASSWORD_EMPTY_ERROR.getCode());
            loginInfo.setMessage(StatusCode.PASSWORD_EMPTY_ERROR.getMessage());
            return loginInfo;
        }

        //用户不存在错误
        LambdaQueryWrapper<UserAccount> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserAccount::getAccount, account);
        queryWrapper.eq(UserAccount::getUseStateCode, "1");
        List<UserAccount> list = accountServiceImpl.list(queryWrapper);
        if (list.size() == 0) {
            loginInfo.setSuccess(false);
            loginInfo.setCode(StatusCode.NOT_EXIST_USER.getCode());
            loginInfo.setMessage(StatusCode.NOT_EXIST_USER.getMessage());
            return loginInfo;
        }
        //用户密码错误
        queryWrapper.eq(UserAccount::getPassword, password);
        list = accountServiceImpl.list(queryWrapper);
        if (list.size() == 0) {
            loginInfo.setSuccess(false);
            loginInfo.setCode(StatusCode.PASSWORD_ERROR.getCode());
            loginInfo.setMessage(StatusCode.PASSWORD_ERROR.getMessage());
            return loginInfo;
        }

        //登录成功
        UserAccount userAccount = list.get(0);
        List<Long> roleIdList = fetchRoleIdList(userAccount.getId());
        userAccount.setRoleIdList(roleIdList);
        String jwtToken = JwtUtils.createJWT(userAccount.getId().toString(), jwtIss, JwtExpires, jwtSecret);
        JwtTokenMap.putToken(userAccount.getId().toString(), jwtToken);
        JwtTokenMap.putUser(jwtToken, userAccount);
        loginInfo.setSuccess(true);
        loginInfo.setCode(StatusCode.SUCCESS.getCode());
        loginInfo.setMessage(StatusCode.SUCCESS.getMessage());
        loginInfo.setToken(jwtToken);
        loginInfo.setData(userAccount);
        return loginInfo;
    }

    /**
     * 添加模型
     *
     * @param actionData 接收参数
     * @return 返回统一结果类型(ResultInfo)
     */
    @Override
    public ResultInfo<UserAccount> add(ActionData<UserAccount> actionData) {
        List<UserAccount> userAccountList = actionData.getData();
        UserAccount userAccount = userAccountList.get(0);
        boolean b = accountServiceImpl.save(userAccount);
        if (b) {
            return JsonResult.success(userAccount);
        } else {
            return JsonResult.error(StatusCode.ERROR_ADD);
        }
    }


    /**
     * 批量添加
     *
     * @param actionData 接收参数
     * @return 返回统一结果类型(ResultInfo)
     */
    @Override
    public ResultInfo<List<UserAccount>> batchAdd(ActionData<UserAccount> actionData) {
        List<UserAccount> userAccountList = actionData.getData();
        boolean b = accountServiceImpl.saveBatch(userAccountList);
        if (b) {
            return JsonResult.success(userAccountList);
        } else {
            return JsonResult.error(StatusCode.ERROR_ADD);
        }
    }

    /**
     * 更新
     *
     * @param actionData 接收参数
     * @return 返回统一结果类型(ResultInfo)
     */
    @Override
    public ResultInfo<UserAccount> update(ActionData<UserAccount> actionData) {
        List<UserAccount> userAccountList = actionData.getData();
        UserAccount component = userAccountList.get(0);
        boolean b = accountServiceImpl.updateById(component);
        if (b) {
            return JsonResult.success(component);
        } else {
            return JsonResult.error(StatusCode.ERROR_UPDATE);
        }
    }

    /**
     * 批量更新
     *
     * @param actionData 接收参数
     * @return 返回统一结果类型(ResultInfo)
     */
    @Override
    public ResultInfo<List<UserAccount>> batchUpdate(ActionData<UserAccount> actionData) {
        List<UserAccount> userAccountList = actionData.getData();
        boolean b = accountServiceImpl.updateBatchById(userAccountList);
        if (b) {
            return JsonResult.success(userAccountList);
        } else {
            return JsonResult.error(StatusCode.ERROR_UPDATE);
        }
    }

    /**
     * 删除
     *
     * @param actionData 接收参数
     * @return 返回统一结果类型(ResultInfo)
     */
    @Override
    public ResultInfo<Integer> delete(ActionData<UserAccount> actionData) {
        return this.batchDelete(actionData);
    }

    /**
     * 批量删除
     *
     * @param actionData 接收参数
     * @return 返回统一结果类型(ResultInfo)
     */
    @Override
    public ResultInfo<Integer> batchDelete(ActionData<UserAccount> actionData) {
        if (!this.validActionData(actionData)) {
            return JsonResult.error(StatusCode.ERROR_INVALID_DELETE);
        }
        QueryWrapper<UserAccount> queryWrapper = this.buildQueryWrapper(actionData, false);
        int delCount = accountServiceImpl.getBaseMapper().delete(queryWrapper);
        if (delCount >= 1) {
            return JsonResult.success(delCount);
        } else {
            return JsonResult.error(StatusCode.ERROR_DELETE);
        }
    }

    /**
     * 根据id进行删除
     *
     * @param actionData 参数
     * @return 返回结果
     */
    @Override
    public ResultInfo<Integer> deleteById(ActionData<UserAccount> actionData) {
        Long id = actionData.getId();
        int delCount = accountServiceImpl.getBaseMapper().deleteById(id);
        if (delCount >= 1) {
            return JsonResult.success(delCount);
        } else {
            return JsonResult.error(StatusCode.ERROR_DELETE);
        }
    }

    /**
     * 根据id数组进行删除
     *
     * @param actionData 参数
     * @return 返回结果
     */
    @Override
    public ResultInfo<Integer> deleteByIds(ActionData<UserAccount> actionData) {
        List<Long> ids = actionData.getIds();
        if (ids == null || ids.size() < 1) {
            return JsonResult.error(StatusCode.ERROR_INVALID_DELETE);
        }
        int delCount = accountServiceImpl.getBaseMapper().deleteBatchIds(ids);
        if (delCount >= 1) {
            return JsonResult.success(delCount);
        } else {
            return JsonResult.error(StatusCode.ERROR_DELETE);
        }
    }

    /**
     * 不会页查询
     *
     * @param actionData 接收参数
     * @return 返回统一结果类型(ResultInfo)
     */
    @Override
    public ResultInfo<List<UserAccount>> query(ActionData<UserAccount> actionData) {
        QueryWrapper<UserAccount> queryWrapper = this.buildQueryWrapper(actionData, false);
        List<UserAccount> list = accountServiceImpl.list(queryWrapper);
        return JsonResult.success(list);
    }

    /**
     * 根据id数组进行简单查询
     *
     * @param actionData 参数
     * @return 返回值
     */
    @Override
    public ResultInfo<List<UserAccount>> queryByIds(ActionData<UserAccount> actionData) throws BusinessException {
        List<Long> ids = actionData.getIds();
        List<UserAccount> list = accountServiceImpl.listByIds(ids);
        list.forEach(d->{
            List<Long> roleIdList = fetchRoleIdList(d.getId());
            d.setRoleIdList(roleIdList);
        });

        return JsonResult.success(list);
    }

    /**
     * 获取角色Id集合
     * @param accountId
     * @return
     */
    private List<Long> fetchRoleIdList(Long accountId) {
        List<AccountRole> accountRoleList = accountRoleService.selectByAccountId(accountId);
        List<Long> roleIdList = accountRoleList.stream().map(e -> e.getRoleId()).collect(Collectors.toList());
        return roleIdList;
    }

    /**
     * 分页查询
     *
     * @param actionData 接收参数
     * @return 返回统一结果类型(ResultInfo)
     */
    @Override
    public ResultInfo<PageInfo> queryByPage(ActionData<UserAccount> actionData) {
        Page<UserAccount> pageInfo = new Page<>(actionData.getPageNumber(), actionData.getPageSize());
        Page<UserAccount> queryPage = accountServiceImpl.page(pageInfo, this.buildQueryWrapper(actionData, false));
        PageInfo pageResult = PageInfo.of(queryPage);
        return JsonResult.success(pageResult);
    }

    /**
     * 分页复杂查询
     *
     * @param actionData 接收参数
     * @return 返回统一结果类型(ResultInfo)
     */
    @Override
    public ResultInfo<PageInfo> complexQuery(ActionData<UserAccount> actionData) {
        QueryWrapper<UserAccount> componentQueryWrapper = this.buildQueryWrapper(actionData);
        Page<UserAccount> pageInfo = new Page<>(actionData.getPageNumber(), actionData.getPageSize());
        Page<UserAccount> queryPage = accountServiceImpl.page(pageInfo, componentQueryWrapper);
        PageInfo pageResult = PageInfo.of(queryPage);
        return JsonResult.success(pageResult);
    }
}
